home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_185 / examples / pgtb / pgtb.zoo / tbsym.c < prev    next >
C/C++ Source or Header  |  1988-12-12  |  7KB  |  233 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\  The Software Distillery                         */
  3. /* |. o.| || Made available to the Amiga development community             */
  4. /* | .    | || the authors:                       BBS:      */
  5. /* | o    | ||   John Mainwaring                     (919)-471-6436  */
  6. /* |  . |//                                     */
  7. /* ======                                     */
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9.  
  10. /* this routine reads the program and extracts symbol and debug information  */
  11.  
  12. #include "tb.h"
  13. #include "setjmp.h"
  14.  
  15. #define HUNK_UNIT     999
  16. #define HUNK_NAME    1000
  17. #define HUNK_CODE    1001
  18. #define HUNK_DATA    1002
  19. #define HUNK_BSS    1003
  20. #define HUNK_RELOC32    1004
  21. #define HUNK_RELOC16    1005
  22. #define HUNK_RELOC8    1006
  23. #define HUNK_EXT    1007
  24. #define HUNK_SYMBOL    1008
  25. #define HUNK_DEBUG    1009
  26. #define HUNK_END    1010
  27. #define HUNK_HEADER    1011
  28. #define HUNK_OVERLAY    1013
  29. #define HUNK_BREAK    1014
  30.  
  31. #define LINE (('L'<<24)|('I'<<16)|('N'<<8)|'E')
  32.  
  33. extern struct tbtemplate *tbdata;
  34. extern jmp_buf bailout;
  35.  
  36. long hunkcount;  /* used to match codefile hunks with PGTB file segments */
  37.  
  38. ULONG readhunk(FILE *);
  39. void skipheaderhunk(FILE *);
  40. void dosymbols(FILE *);
  41. void dolines(FILE *);
  42.  
  43. int readsym(file)
  44. FILE *file;
  45. {
  46. ULONG thishunk, lasthunk = 0;
  47.  
  48. if (setjmp(bailout))
  49.    /* get here if file utilities decide to abort quasi gracefully */
  50.    return(0);
  51.  
  52. hunkcount = -1;  /* so first hunk will be 0 */
  53.  
  54. while (thishunk = readhunk(file))
  55.    lasthunk = thishunk;
  56.  
  57. return(lasthunk == HUNK_END);
  58. }
  59.  
  60. ULONG readhunk(file)
  61. FILE *file;
  62. {
  63. ULONG hunkid, size;
  64.  
  65. if (!(hunkid = forcegetlong(file)))
  66.    return(0);  /* signal end of file (or confusion?) */
  67.  
  68. switch (hunkid) {
  69. case HUNK_CODE:     /* these hunks should match a segment but are    */
  70. case HUNK_DATA:     /* otherwise of no interest            */
  71.    hunkcount += 1;    /* fall through to skip over hunk        */
  72. case HUNK_UNIT:     /* these hunks have size and data which is of    */
  73. case HUNK_NAME:     /* no interest to us                */
  74.    skiplong(file, getlong(file));
  75.    break;
  76. case HUNK_BSS:        /* this hunk has only a size            */
  77.    getlong(file);
  78.    hunkcount += 1;    /* but it does create a segment         */
  79.    break;
  80. case HUNK_RELOC32:    /* not interested in relocation info, which is    */
  81. case HUNK_RELOC16:    /* size, reloc hunk num, and size longwords of    */
  82. case HUNK_RELOC8:    /* info.  Ends with size of 0.            */
  83.    while (size = getlong(file))
  84.       skiplong(file, size + 1);
  85.    break;
  86. case HUNK_EXT:        /* should only be found in unlinked *.o files    */
  87.    fprintf(stderr, "*** encountered HUNK_EXT: I give up\n");
  88.    return(0);
  89.    /* break;  happens, but confuses compiler  */
  90. case HUNK_SYMBOL:    /* Oh joy!  my life is worthwhile        */
  91.    dosymbols(file);
  92.    break;
  93. case HUNK_DEBUG:    /* My cup overflows                */
  94.    dolines(file);
  95.    break;
  96. case HUNK_END:        /* end of a group of hunks - no info here    */
  97.    break;
  98. case HUNK_HEADER:    /* some neat admin stuff we can skip over    */
  99.    skipheaderhunk(file);
  100.    break;
  101. case HUNK_OVERLAY:    /* bunt on this for now...            */
  102.    fprintf(stderr, "*** Overlays confuse me, I give up\n");
  103.    return(0);
  104.    /* break;  happens, but confuses compiler  */
  105. case HUNK_BREAK:    /* end of some overlays             */
  106.    break;
  107. default:
  108.    fprintf(stderr, "*** illegal hunkid %ld in program file\n", hunkid);
  109.    return(0);  /* caller will give up now */
  110. }
  111. return(hunkid);
  112. }
  113.  
  114. void skipheaderhunk(file)
  115. /*   --------------*/
  116. FILE *file;
  117. {
  118. ULONG size, first, last;
  119. long i;
  120.  
  121. /* do the names, which consist of a (possibly empty) list of    */
  122. /* {size, ASCII} terminated by a null size            */
  123. while (size = getlong(file))
  124.    skiplong(file, size);
  125.  
  126. getlong(file);          /* table size - who needs it?           */
  127. first = getlong(file);
  128. last = getlong(file);
  129.  
  130. if (tbdata->segcount != (last - first + 1))
  131.    {
  132.    fprintf(stderr, "*** code file hunk count does not match traceback\n");
  133.    longjmp(bailout, 1);  /* abort */
  134.    }
  135.  
  136. for (i = 0; i < tbdata->segcount; i++)
  137.    {
  138.    if ((size = getlong(file)) != tbdata->segments[i].size >> 2)
  139.       {
  140.       fprintf(stderr, "*** segment %ld length $%lx != hunk length $%lx\n",
  141.            i, size, tbdata->segments[i].size >> 2);
  142.       longjmp(bailout, 1);  /* abort */
  143.       }
  144.    }
  145. }
  146.  
  147. void dosymbols(file)
  148. /*   ---------*/
  149. FILE *file;
  150. {
  151. struct symbol_node *symaddr, *memaddr;
  152. long memsize;
  153. ULONG size;
  154.  
  155. while (size = getlong(file))
  156.    {
  157.    /* size includes extra word for null to terminate string    */
  158.    memsize = sizeof(struct symbol_node) + size << 2;
  159.    if (!(memaddr = (struct symbol_node *)AllocMem(memsize, MEMF_CLEAR)))
  160.       {
  161.       fprintf(stderr, "*** memory allocation failed\n");
  162.       exit(FATAL);
  163.       }
  164.    memaddr->sn_memsize = memsize;
  165.    getblock(file, (ULONG *)&(memaddr->sn_sym[0]), size);
  166.    memaddr->sn_value = getlong(file) + tbdata->segments[hunkcount].addr;
  167.    symaddr = (struct symbol_node *)&(tbdata->segments[hunkcount].symbols);
  168.    while (symaddr->sn_next)
  169.       {
  170.       if (symaddr->sn_next->sn_value > memaddr->sn_value)
  171.      break;
  172.       else if (symaddr->sn_next->sn_value == memaddr->sn_value)
  173.      /* see if names match - don't discard aliases          */
  174.      if (strcmp(symaddr->sn_next->sn_sym, memaddr->sn_sym) == 0)
  175.         /* we gots this one awready - chuck it    */
  176.         {
  177.         FreeMem((char *)memaddr, memaddr->sn_memsize);
  178.         memaddr = 0;
  179.         }
  180.      /* else drop through - might match another alias    */
  181.       symaddr = symaddr->sn_next;
  182.       }
  183.    if (memaddr) /* we didn't deallocate */
  184.       {
  185.       memaddr->sn_next = symaddr->sn_next;
  186.       symaddr->sn_next = memaddr;
  187.       }
  188.    }
  189. }
  190.  
  191. void dolines(file)
  192. /*   -------*/
  193. FILE *file;
  194. {
  195. /* fprintf(stderr, "found debug hunk\n");               */
  196. ULONG size, memsize, htype;
  197. char htypes[5];
  198. struct line_node *memaddr, *lineaddr;
  199.  
  200. size = getlong(file);
  201. memsize = (size << 2) + sizeof(struct line_node) - 16;
  202. if ((memaddr = (struct line_node *)AllocMem(memsize, MEMF_CLEAR)) == 0)
  203.    {
  204.    fprintf(stderr, "*** unable to allocate line memory\n");
  205.    skiplong(file, size);
  206.    return;
  207.    }
  208. memaddr->ln_size = memsize;
  209. memaddr->ln_offset = getlong(file);
  210.  
  211. if ((htype = getlong(file)) != LINE)
  212.    {
  213.    longtoascii(htype, htypes);
  214.    fprintf(stderr, "*** unknown debug hunk type %lx = %s\n", htype, htypes);
  215.    skiplong(file, size-2);
  216.    FreeMem((char *)memaddr, memsize);
  217.    return;
  218.    }
  219.  
  220. getblock(file, (ULONG *)&memaddr->ln_nsize, size-2);
  221. lineaddr = (struct line_node *)&(tbdata->segments[hunkcount].lines);
  222. while (lineaddr->ln_next)
  223.    {
  224.    if (lineaddr->ln_next->ln_offset > memaddr->ln_offset)
  225.       break;
  226.    lineaddr = lineaddr->ln_next;
  227.    }
  228. memaddr->ln_next = lineaddr->ln_next;
  229. lineaddr->ln_next = memaddr;
  230. /* for now just skip the debug hunk            */
  231. /* skiplong(file, getlong(file));                       */
  232. }
  233.